﻿/* Copyright (C) Siemens AG, 2012. All Rights Reserved.
 * Author: Roland Eckl, Corporate Technology
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System.Collections.Generic;
using RVM.Infrastructure.Communication;


namespace RVM.Infrastructure
{
    /// <summary>
    /// Registry for all exported RemotableViewModels.
    /// This registry can be accessed remotely, which allows to import specific
    /// viewmodel's there.
    /// The registry is designed as a singleton, to ensure there is only one object
    /// per process/appdomain which can be accessed through boundaries and knows
    /// about all exported viewmodels within in these boundaries.
    /// </summary>
    public class ViewModelRegistry
    {
        #region To be (singleton) or not to be

        /// <summary>
        /// Private instance of the singleton.
        /// </summary>
        private static readonly ViewModelRegistry _shared = new ViewModelRegistry();

        /// <summary>
        /// Public constructor.
        /// </summary>
        public ViewModelRegistry()
        {
        }

        /// <summary>
        /// Public accessor to the singleton instance.
        /// </summary>
        public static ViewModelRegistry Shared
        {
            get { return _shared; }
        }

        #endregion

        #region Private Members

        /// <summary>
        /// Dictionary that holds all exported viewmodels from this process/appdomain.
        /// </summary>
        private readonly Dictionary<string, RemotableViewModel> _registry =
            new Dictionary<string, RemotableViewModel>();

        #endregion

        #region Public Members

        /// <summary>
        /// Count of exported viewmodels.
        /// </summary>
        public int Count { get { return _registry.Count; } }

        #endregion

        #region Public Methods

        /// <summary>
        /// Adds a RemotableViewModel to the registry. This method is used
        /// when exporting a viewmodel.
        /// </summary>
        /// <param name="vmt">Unique ID of viewmodel, which identifies the exported viewmodel instance</param>
        /// <param name="vm">Actual viewmodel that has to be exported through this registry</param>
        public void Add(string vmt, RemotableViewModel vm)
        {
            _registry.Add(vmt, vm);
        }

        /// <summary>
        /// Gets a viewmodel, identified through the desired type.
        /// </summary>
        /// <param name="t">Type of viewmodel that is requested</param>
        /// <returns>RemotableViewModel of desired type</returns>
        public RemotableViewModel Get(string t)
        {
            return _registry[t];
        }

        /// <summary>
        /// Checks whether a viewmodel with given ID got already registered or not.
        /// </summary>
        /// <param name="t">Type of ViewModel</param>
        /// <returns>TRUE, of corresponding viewmodel is currently exported</returns>
        public bool Contains(string t)
        {
            return _registry.ContainsKey(t);
        }

        /// <summary>
        /// Removes an agent from all registered viewmodels.
        /// (Used when an agent fails, etc.)
        /// </summary>
        /// <param name="agent">the actual agent to remove</param>
        public void RemoveAgentFromAll(IViewModelAgent agent)
        {
            foreach(RemotableViewModel rvm in _registry.Values)
            {
                rvm.RemoveViewModelAgent(agent);
            }
        }

        #endregion
    }
}
